package com.wiscamp.ninechapters.challenges.domain.services;

import com.wiscamp.ninechapters.challenges.domain.models.Medal;
import com.wiscamp.ninechapters.challenges.domain.models.UserMedal;
import com.wiscamp.ninechapters.challenges.domain.repositories.MedalsRepository;
import cube.ddd.aspect.AopServiceException;
import com.wiscamp.ninechapters.ddd.DomainService;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Objects;

/**
 * Medal Service
 */
@Service
public class MedalsService implements DomainService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MedalsRepository medalsRepository;

    @Autowired
    public MedalsService(MedalsRepository medalsRepository) {

        this.medalsRepository = medalsRepository;
    }

    /**
     * Awards a medal
     *
     * @param userId
     * @param medalId
     */

    @AopServiceException
    public void awardMedal(@Min(0) long userId, @Min(0) long medalId) {
        var userMedal = new UserMedal();
        userMedal.setMedalId(medalId);
        userMedal.setUserId(userId);
        medalsRepository.saveUserMedal(userMedal);
    }

    /**
     * Awards a medal
     *
     * @param userId
     * @param medalCode
     */

    @AopServiceException
    public void awardMedal(@Min(0) long userId, @NotBlank String medalCode) {
        var medal = getMedalByCode(medalCode);
        if (Objects.nonNull(medal)) {
            awardMedal(userId, medal.getMedalId());
        }
    }


    /**
     * Gets user's medals
     *
     * @param userId
     * @return
     */

    @AopServiceException
    public Collection<Medal> getUserMedals(@Min(0) long userId) {
        return medalsRepository.getUserMedals(userId);
    }

    /**
     * Creates a medal
     *
     * @param medal
     * @return
     */

    @AopServiceException
    public Medal createMedal(@NotNull Medal medal) {
        medal.setCreateTime(LocalDateTime.now());
        medal.setEditTime(LocalDateTime.now());
        return medalsRepository.saveMedal(medal);
    }

    /**
     * Gets a medal
     *
     * @param medalCode
     * @return
     */

    @AopServiceException
    public Medal getMedalByCode(@NotBlank String medalCode) {
        return medalsRepository.getMedalByCode(medalCode);
    }
}
